import { Injectable } from '@nestjs/common';
import Client from 'ali-oss';
import ossConfig from '../config/ossConfig';
import * as OSS from 'ali-oss';
import * as path from 'node:path';
import { CreateFileDto } from './dto/create-file.dto';
import OssConfig from '../config/ossConfig';
// @ts-ignore
import * as dayjs from 'dayjs';

@Injectable()
export class OssService {
  public client: Client;
  private ossConfig: typeof OssConfig;

  public constructor() {
    this.ossConfig = {
      accessKeyId: ossConfig.accessKeyId,
      accessKeySecret: ossConfig.accessKeySecret,
      region: ossConfig.region,
      bucket: ossConfig.bucket,
      endpoint: ossConfig.endpoint,
    };
    this.client = new OSS(ossConfig);
  }

  /**
   * 上传本地文件
   * @returns {Promise<void>}
   * @param createFileDto
   */
  async uploadLocalFile(createFileDto: CreateFileDto) {
    try {
      // 自定义请求头
      const headers = {
        // 指定Object的存储类型。
        'x-oss-storage-class': 'Standard',
        // 指定Object的访问权限。
        'x-oss-object-acl': 'public-read',
        // 通过文件URL访问文件时，指定以附件形式下载文件，下载后的文件名称定义为example.txt。
        // 'Content-Disposition': 'attachment; filename="example.txt"',
        // 设置Object的标签，可同时设置多个标签。
        'x-oss-tagging': 'Tag1=1&Tag2=2',
        // 指定PutObject操作时是否覆盖同名目标Object。此处设置为true，表示禁止覆盖同名Object。
        'x-oss-forbid-overwrite': 'true',
        secure: true,
      };
      const options = {
        headers,
      };

      try {
        // 填写OSS文件完整路径和本地文件的完整路径。OSS文件完整路径中不能包含Bucket名称。
        // 如果本地文件的完整路径中未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        const result = await this.client.put(
          createFileDto.ossPath,
          path.normalize(createFileDto.localFilePath),
          // 自定义headers
          options,
        );
        return {
          data: result,
        };
      } catch (e) {
        console.log(e);
        return {
          msg: e,
          status: 201,
        };
      }
    } catch (error) {
      console.error('发生错误:', error);
      // 在此处添加错误处理逻辑。
    }
  }

  async getSignature() {
    const date = new Date();
    // 时长加 1 天，作为签名的有限期
    date.setDate(date.getDate() + 1);
    const policy = {
      // 设置签名的有效期，格式为Unix时间戳
      expiration: date.toISOString(),
      conditions: [
        ['content-length-range', 0, 10485760000], // 设置上传文件的大小限制
      ],
    };
    // 生成签名，策略等信息
    const formData = this.client.calculatePostSignature(policy);

    let host = '';
    if (this.ossConfig.endpoint) {
      host = `http://${this.ossConfig.endpoint}`;
    } else {
      // 生成 bucket 域名，客户端将向此地址发送请求
      const location = await this.client.getBucketLocation(ossConfig.bucket);
      host = `http://${this.ossConfig.bucket}.${location.location}.aliyuncs.com`;
    }
    console.log(host, 'host');
    // 响应给客户端的签名和策略等信息
    const dateTimestamp = dayjs().add(1, 'days').unix();

    return {
      data: {
        expire: dayjs.unix(dateTimestamp).format('YYYY-MM-DD HH:mm:ss'),
        policy: formData.policy,
        signature: formData.Signature,
        accessId: formData.OSSAccessKeyId,
        host,
        dir: 'data/',
      },
    };
  }

  download(filename: string) {
    const response = {
      'content-disposition': `attachment; filename=${encodeURIComponent(filename)}`,
    };
    return {
      data: this.client.signatureUrl(filename, {
        expires: 3600,
        response,
      }),
    };
  }
}
